package timeUtil

import (
	"fmt"
	"github.com/gogf/gf/v2/os/gtime"
	"github.com/gogf/gf/v2/util/gconv"
	"math"
	"strconv"
	"time"
)

func CheckAeSecValid(sec int) bool {
	timestamp := int64(sec)
	//t := time.Unix(timestamp, 0)
	//if t.Year() < 2022 {
	//	return false
	//}
	now := gtime.Now().Unix()
	const dif = float64(24 * 3600 * 30)
	gap := math.Abs(float64(timestamp - now))
	if gap > dif {
		return false
	}
	return true
}

func GetJoinSecNs(sec uint64, ns uint64) uint64 {
	return uint64(sec*1000000000 + ns)
}

func GetJoinSecNsToMicroSec(sec uint64, ns uint64) uint64 {
	return uint64(sec*1000000 + +(ns / 1000))
}

func FormatSecNsToMicroStr(sec int64, ns int64) string {
	date := time.Unix(int64(sec), int64(ns)).Format("2006-01-02 15:04:05.000000")
	return date
}

func FormatSecNsToMilStr(sec int64, ns int64) string {
	date := time.Unix(int64(sec), int64(ns)).Format("2006-01-02 15:04:05.000")
	return date
}

func Timestamp2Datetime(t int64) string {
	date := time.Unix(t, 0).Format("2006-01-02 15:04:05")
	return date
}

func Datetime2Timestamp(str string) int64 {
	tmp := "2006-01-02 15:04:05"
	res, _ := time.ParseInLocation(tmp, str, time.Local)
	return res.Unix()
}

// 获取临近的ym   currentYYYYMM当前年月
func GetNearMonthYmByYm(currentYYYYMM string) (prevYYYYMM, nextYYYYMM string) {
	// 解析当前年月
	year, _ := strconv.Atoi(currentYYYYMM[:4])
	month, _ := strconv.Atoi(currentYYYYMM[4:])
	// 计算上一个年月
	prevMonth := month - 1
	prevYear := year
	if prevMonth == 0 {
		prevMonth = 12
		prevYear--
	}
	prevYYYYMM = fmt.Sprintf("%d%02d", prevYear, prevMonth)

	// 计算下一个年月
	nextMonth := month + 1
	nextYear := year
	if nextMonth == 13 {
		nextMonth = 1
		nextYear++
	}
	nextYYYYMM = fmt.Sprintf("%d%02d", nextYear, nextMonth)
	return
}

func GetNowAndNextMonthYM() (now1 string, next1 string) {

	now := time.Now()
	now1 = fmt.Sprintf("%04d%02d", now.Year(), int(now.Month()))

	//lastMonth := now.AddDate(0, -1, 0)
	nextMonth := now.AddDate(0, 1, 0)
	next1 = fmt.Sprintf("%04d%02d", nextMonth.Year(), int(nextMonth.Month()))

	return
}

func GetLastMonthYm() int {
	now := time.Now()
	lastMonth := now.AddDate(0, -1, 0)
	lastMonth1 := fmt.Sprintf("%04d%02d", lastMonth.Year(), int(lastMonth.Month()))
	return gconv.Int(lastMonth1)
}

func ConvertTimeIntToYm(sec int) (res string) {
	timestamp := int64(sec)
	t := time.Unix(timestamp, 0)
	res = fmt.Sprintf("%04d%02d", t.Year(), int(t.Month()))
	return res
}

func ConvertTimeIntToYmdhmDir(sec int) (res string) {
	timestamp := int64(sec)
	t := time.Unix(timestamp, 0)
	res = fmt.Sprintf("%04d/%02d/%02d/%02d/%02d", t.Year(), int(t.Month()), t.Day(), t.Hour(), t.Minute())
	return res
}

func ConvertSecnsToYm(secns string) string {
	// 假设有一个纳秒级时间戳
	nanoTimestamp := gconv.Int64(secns)

	// 将纳秒级时间戳转换为秒级时间戳
	secTimestamp := nanoTimestamp / int64(time.Second)

	return ConvertTimeIntToYm(int(secTimestamp))
}

// 将秒级时间戳转换为该月份的第一天的时间戳
func getStartOfMonth(t time.Time) time.Time {
	// 获取该时间所在月的第一天
	year, month, _ := t.Date()
	return time.Date(year, month, 1, 0, 0, 0, 0, time.UTC)
}

// GetYearMonthsBetween 返回两个时间戳之间的所有月份（格式为 yyyymm）
func GetYearMonthsBetween(startTimestamp, endTimestamp int64) ([]int64, error) {
	// 安全检查：开始时间必须小于或等于结束时间
	if startTimestamp > endTimestamp {
		return nil, fmt.Errorf("start timestamp must be less than or equal to end timestamp")
	}
	// 将秒级时间戳转换为time.Time类型
	startTime := time.Unix(startTimestamp, 0)
	endTime := time.Unix(endTimestamp, 0)

	// 获取起始时间所在月份的第一天
	startOfMonth := getStartOfMonth(startTime)
	// 获取结束时间所在月份的第一天
	endOfMonth := getStartOfMonth(endTime)

	// 用于存储所有的yyyyMM格式的时间字符串
	// 定义结果数组
	var months []int64
	// 循环，直到当前时间超过结束时间
	count := 1
	// 从startOfMonth到endOfMonth遍历每个月
	for startOfMonth.Before(endOfMonth) || startOfMonth.Equal(endOfMonth) {
		// 格式化当前月份为yyyyMM
		monthStr := startOfMonth.Format("200601")
		thisMonthint := int64(gconv.Int(monthStr))
		months = append(months, thisMonthint)
		count++
		// 移动到下一个月
		startOfMonth = startOfMonth.AddDate(0, 1, 0)
		// 不想找到太多的月份 无意义
		if count > 100 {
			break
		}
	}
	//从最新的时间往旧排
	return months, nil
}
